package com.jiuhaohealth.kangxun360.aspectj;

import java.lang.reflect.Method;

import org.apache.commons.beanutils.BeanUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import com.jiuhaohealth.common.datasource.MultiDataSource;
import com.jiuhaohealth.kangxun360.chooser.Kangxun360DataSourceChooser;

@Aspect
@Component
public class Kanxun360ServiceAspectj {

	protected final static Logger logger = LoggerFactory.getLogger(Kanxun360ServiceAspectj.class);
	
	@Around("execution(@com.jiuhaohealth.kangxun360.aspectj.ChooseDateSourceByUid * *(..))" +
	"" )
	public Object chooseDataSourceByUid(ProceedingJoinPoint jp) throws Throwable {
		Object[] objs = jp.getArgs();
		long userId = getUid(jp);
		if(userId == 0)
			throw new Exception("UserId must not be zero!!!!!!!");
			MultiDataSource.chooseDateSource(new Kangxun360DataSourceChooser(userId));	//切换数据源
		try {
			return jp.proceed(objs);
		} catch (Exception e) {
			logger.error("ChooseDateSourceByUid's args and num is wrong!!!!!!", e);
			throw e;
		} finally {
			MultiDataSource.removeDataSourceKey();	//清除数据源标识，回到默认
		}
	} 
	
	private long getUid(JoinPoint point) throws Exception {
		//拦截的实体类
		Object target = point.getTarget();
		//拦截的方法名
		String methodName = point.getSignature().getName();
		//拦截的方法参
		Object[] args = point.getArgs();
		//拦截的放参数类型
		Class<?>[] parameterTypes = ((MethodSignature)point.getSignature()).getMethod().getParameterTypes();
		
		Method method = target.getClass().getMethod(methodName, parameterTypes);
		String num = method.getAnnotation(ChooseDateSourceByUid.class).num();
		String arg = method.getAnnotation(ChooseDateSourceByUid.class).arg();
		Object orgs = args[Integer.valueOf(num)];
		if(arg.equals("this")) {
			return Long.valueOf(orgs.toString());
		} else if(arg.startsWith("this.") && arg.length()>5) {
			return Long.valueOf(BeanUtils.getProperty(orgs, arg.substring(5)));
		} else {
			throw new Exception("ChooseDateSourceByUid's args and num is wrong");
		}
		
	}
}
